﻿using FFmpeg.AutoGen;
using FFmpegWinui3.UlitFolder;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Controls.Primitives;
using Microsoft.UI.Xaml.Data;
using Microsoft.UI.Xaml.Input;
using Microsoft.UI.Xaml.Media;
using Microsoft.UI.Xaml.Navigation;
using NAudio.Wave;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.WindowsRuntime;
using System.Threading.Tasks;
using Windows.Foundation;
using Windows.Foundation.Collections;

// To learn more about WinUI, the WinUI project structure,
// and more about our project templates, see: http://aka.ms/winui-project-info.

namespace FFmpegWinui3.Views
{
    /// <summary>
    /// An empty page that can be used on its own or navigated to within a Frame.
    /// </summary>
    public unsafe sealed partial class FFmpegAudioVideo : Page
    {
        //播放状态
        private bool isPlaying = false;

        //缓存时间（ms）
        const int BUFFER_DURATION = 2000;
        //NAudio音频播放组件
        private WaveOut waveOut;
        private BufferedWaveProvider bufferedWaveProvider;
        public FFmpegAudioVideo()
        {
            this.InitializeComponent();
            Init();
        }

        DecodecAudio audio;


        /// <summary>
        /// 做一些初始化操作
        /// </summary>
        private void Init()
        {
            waveOut = new WaveOut();
            bufferedWaveProvider = new BufferedWaveProvider(new WaveFormat());
            waveOut.Init(bufferedWaveProvider);
            waveOut.Play();

            play.Click += (s, e) =>
            {
                isPlaying = true;
                isInitOk = false;
                audio = new DecodecAudio();
                var i = audio.init_ffmpeg(pathBox.Text);
                if (i >= 0)
                {
                    isInitOk = true;
                }
            };

            Task.Run(() =>
            {
                Player();
            });
        }
        bool isInitOk;
        /// <summary>
        /// 播放
        /// </summary>
        void Player()
        {





            TimeSpan audioMaxBufferedDuration = new TimeSpan(0, 0, 0, 0, BUFFER_DURATION); //音频最大缓冲时间

            while (true)
            {
                if (isInitOk&& isPlaying && audio != null)
                {

                    int i = audio.read_frame(); //读取一帧 1:音频 2:视频
                    if (i == 1)
                    {
                        if (bufferedWaveProvider.BufferedDuration.CompareTo(audioMaxBufferedDuration) > 0)
                        {
                            bufferedWaveProvider.ClearBuffer();
                        }

                        IntPtr audioFrame = audio.get_audio_frame(); //一帧音频句柄
                        int bufSize = audio.get_audio_buffer_size(); //一帧音频占用大小
                        byte[] bytes = new byte[bufSize];
                        Marshal.Copy(audioFrame, bytes, 0, bufSize); //拷贝句柄中的音频到bytes
                        bufferedWaveProvider.AddSamples(bytes, 0, bufSize);//向缓存中添加音频样本
                    }
                    else if (i == 2)
                    {
                        //Dispatcher.Invoke(new Action(delegate
                        //{
                        //    BitmapSource bs = BitmapImage.Create(
                        //        get_video_width(),
                        //        get_video_height(),
                        //        0,
                        //        0,
                        //        PixelFormats.Rgb24,
                        //        null,
                        //        get_video_frame(),
                        //        get_video_buffer_size(),
                        //        (get_video_width() * PixelFormats.Rgb24.BitsPerPixel + 7) / 8);
                        //    Thread t = new Thread(new ParameterizedThreadStart(playVideo));
                        //    t.Start(bs);
                        //}));
                    }
                }

                //try
                //{
                //    audio.release();
                //}
                //catch (Exception e)
                //{
                //    Console.WriteLine(e);
                //}
            }
        }

        /// <summary>
        /// 播放视频，单独开线程，是为了和音频有同步的缓存时间
        /// </summary>
        void playVideo(object bs)
        {
            //int time = BUFFER_DURATION - 300;
            //if (time > 0)
            //{
            //    Thread.Sleep(time);
            //}
            //Dispatcher.BeginInvoke(new Action(delegate { videoImg.Source = bs as BitmapSource; }));
        }

        /// <summary>
        /// 将字符串分配到非托管区，并返回该非托管区句柄
        /// </summary>
        /// <param name="strData">字符串</param>
        /// <returns>非托管区句柄</returns>
        private IntPtr mallocIntPtr(String strData)
        {
            //字符串转化为字节
            Byte[] bytesData = System.Text.Encoding.Default.GetBytes(strData);

            //分配非托管区内存
            IntPtr ptr = Marshal.AllocHGlobal(bytesData.Length);

            //清空非托管区
            Byte[] emptyBytes = new Byte[bytesData.Length + 1]; //一定要加1,否则后面是乱码，原因未找到
            Marshal.Copy(emptyBytes, 0, ptr, emptyBytes.Length);

            //往非托管区塞数据
            Marshal.Copy(bytesData, 0, ptr, bytesData.Length);

            return ptr;
        }
    }
}



